#include "sTRFrame.h"
#include "sRenderTarget.h"
#include "sGui.h"

namespace sgui
{
namespace res
{    

// -------------------------------- sFrameObject --------------------------------

sLinkTo<sTextureResourceModule>& sTextureResourceFrame::sFrameObject::getModule()
{
	return m_module;
}

obj::sTransform& sTextureResourceFrame::sFrameObject::getTransform()
{
	return m_transform;
}

void sTextureResourceFrame::sFrameObject::load(const db::Record &file)
{
	m_transform.load(file[L"transform"]);
	m_module.load(file[L"module"]);
}

void sTextureResourceFrame::sFrameObject::save(db::Record &file) const
{
	m_transform.save(file[L"transform"]);
	m_module.save(file[L"module"]);
}

void sTextureResourceFrame::sFrameObject::clear()
{
	m_module.clear();
	m_transform.clear();
}

#ifdef _EDITOR
void sTextureResourceFrame::sFrameObject::exportRTTI(rtti::sInfoList& list)
{
	REGISTER_RTTI(L"Transform", TEXT, NEW_RTTI_CLASS_PARAMETER(m_transform));
}
#endif
		
sTextureResourceFrame::sFrameObject::sFrameObject(sGUI& gui) :
	sGUIObject(gui),
	m_module(gui)
{
}

sTextureResourceFrame::sFrameObject::sFrameObject(sGUI& gui, sTextureResourceModule* module) :
	sGUIObject(gui),
	m_module(gui, module)
{
}

// -------------------------------- sTextureResourceFrame ------------------------------
	
void sTextureResourceFrame::draw(engine::sDrawStack& drawStack, const math::sRectf& rect) const
{
	if (m_renderTarget)
	{
		m_renderTarget->draw(rect, m_stretch);
	}
}

void sTextureResourceFrame::load(const db::Record &file)
{
	sNamedObject::load(file);
	const db::Record &objects = file[L"obj"];
	for (u32 i = 0, t = objects.getSize(); i < t; i++)
	{
		sFrameObject *obj = new sFrameObject(getGui());
		obj->load(objects[i]);
		m_objects.push_back(obj);
	}
}

void sTextureResourceFrame::save(db::Record &file) const
{
	sNamedObject::save(file);
	db::Record &objects = file[L"obj"];
	objects.setSize(m_objects.size());
	u32 idx = 0;
	for (std::deque<sFrameObject*>::const_iterator it = m_objects.begin(); it != m_objects.end(); it++)
	{
		(*it)->save(objects[idx++]);
	}
}


std::deque<sTextureResourceFrame::sFrameObject*>& sTextureResourceFrame::getObjects()
{
	return m_objects;
}

const std::deque<sTextureResourceFrame::sFrameObject*>& sTextureResourceFrame::getObjects() const
{
	return m_objects;
}

void sTextureResourceFrame::clear()
{
	for (std::deque<sFrameObject*>::iterator it = m_objects.begin(); it != m_objects.end(); it++)
	{
		delete *it;
	}
	m_objects.clear();
}
		
void sTextureResourceFrame::update()
{
	if (m_renderTarget)
	{
		engine::sDrawStack tmpStack(getGui(), *m_renderTarget);
		m_renderTarget->beginRender(tmpStack);

		for (std::deque<sFrameObject*>::const_iterator it = m_objects.begin(); it != m_objects.end(); it++)
		{
			sFrameObject *obj = *it;
			sTextureResourceModule *module = obj->getModule().get();
			if (module)
			{
				tmpStack.top()->pushTransform(obj->getTransform());
				module->draw(tmpStack);
				tmpStack.top()->popTransform();
			}
		}

		m_renderTarget->endRender(tmpStack);
	}
}

void sTextureResourceFrame::setSize(const math::sPointf& size)
{
	m_surfaceSize = size;

	if (m_renderTarget)
	{
		delete m_renderTarget;
	}
	m_renderTarget = getGui().getEngine().getRenderTarget(m_surfaceSize);
}

#ifdef _EDITOR
void sTextureResourceFrame::exportRTTI(rtti::sInfoList& list)
{

}

#endif

sTextureResourceFrame::sTextureResourceFrame(sGUI& gui, const std::wstring& name) :
	sNamedObject(gui, name),
	m_renderTarget(NULL)
{

}

sTextureResourceFrame::~sTextureResourceFrame()
{
	clear();
}

	

};
};
